#ifndef __TIMER__H
#define __TIMER__H
/**
 * 定时器模块
 */
#include "linklist.h"
#include <array>
#include <cstdint>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
////////////////////////////////////////////////////////////////////////////////////////
// 时间轮定时器

// 第1个轮占的位数
#define TVR_BITS 8
// 第1个轮的长度
#define TVR_SIZE (1 << TVR_BITS)
// 第n个轮占的位数
#define TVN_BITS 6
// 第n个轮的长度
#define TVN_SIZE (1 << TVN_BITS)
// 掩码：取模或整除用
#define TVR_MASK (TVR_SIZE - 1)
#define TVN_MASK (TVN_SIZE - 1)

// 定时器回调函数
typedef void (*timer_cb_t)(void*);

// 定时器结点
typedef struct timernode {
    struct linknode* next; // 下一个结点
    struct linknode* prev; // 上一个结点
    void* userdata;        // 用户数据
    timer_cb_t callback;   // 回调函数
    uint32_t expire;       // 到期时间
} timernode_t;

// 第1个轮
typedef struct tvroot {
    clinknode_t vec[TVR_SIZE];
    // std::array<clinknode_t, TVR_SIZE> vec;
} tvroot_t;

// 后面几个轮
typedef struct tvnum {
    clinknode_t vec[TVN_SIZE];
    // std::array<clinknode_t, TVN_SIZE> vec;
} tvnum_t;

struct TimerNode {
    void* userdata;      // 用户数据
    timer_cb_t callback; // 回调函数
    uint32_t expire;     // 到期时间
};

struct TimerRoot {
    std::array<std::list<TimerNode>, TVR_SIZE> eventroot;
};

struct TimerTn {
    std::array<std::list<TimerNode>, TVN_SIZE> eventn;
};

#define FIRST_INDEX(v) ((v)&TVR_MASK)
#define NTH_INDEX(v, n) (((v) >> (TVR_BITS + (n)*TVN_BITS)) & TVN_MASK)

class Timerwheel {
private:
    uint64_t lasttime;  // 上一次时间毫秒
    uint32_t currtick;  // 当前的tick
    uint16_t interval;  // 每个时间点的毫秒间隔
    uint16_t remainder; // 剩余的毫秒
    TimerRoot tvroot;   // 1个基层
    TimerTn tv[4];      // 4个上层

    int __addnode(TimerNode&);

protected:
    int __addnode2wheel(TimerNode& node, uint32_t utick);

public:
    Timerwheel(uint16_t interval)
        : interval(interval)
    {
    }
    virtual ~Timerwheel() { }
};

int Timerwheel::__addnode(TimerNode& node)
{
    uint32_t expire = node.expire;
    uint32_t driff = expire - currtick; //两个tick相减
    if (driff < TVR_SIZE)               //可以直接往最下层放
    {
        this->tvroot.eventroot[FIRST_INDEX(expire)].push_back(node);
    } else {
        uint64_t sz = 0;
        for (int i = 0; i < 4; ++i) {
            sz = (1UL << (TVR_BITS + (i + 1) * TVN_BITS));
            if (driff < sz) {
                this->tv[i].eventn[NTH_INDEX(driff,i)].push_back(node);
                break;
            }
        }
    }
    return 0;
}

int Timerwheel::__addnode2wheel(TimerNode& node, uint32_t utick)
{
    node.expire = currtick + ((utick > 0) ? (utick) : (1));

    return __addnode(node);
}

// 时间轮定时器
typedef struct timerwheel {
    tvroot_t tvroot;    // 第1个轮
    tvnum_t tv[4];      // 后面4个轮
    uint64_t lasttime;  // 上一次的时间毫秒
    uint32_t currtick;  // 当前的tick
    uint16_t interval;  // 每个时间点的毫秒间隔
    uint16_t remainder; // 剩余的毫秒
} timerwheel_t;

// 初始化时间轮，interval为每帧的间隔，currtime为当前时间
void timerwheel_init(timerwheel_t* tw, uint16_t interval, uint64_t currtime);
// 初始化时间结点：cb为回调，ud为用户数据
void timerwheel_node_init(timernode_t* node, timer_cb_t cb, void* ud);
// 增加时间结点，ticks为触发间隔(注意是以interval为单位)
void timerwheel_add(timerwheel_t* tw, timernode_t* node, uint32_t ticks);
// 删除结点
int timerwheel_del(timerwheel_t* tw, timernode_t* node);
// 更新时间轮
void timerwheel_update(timerwheel_t* tw, uint64_t currtime);

#endif
